package main

import (
	"context"
	"fmt"
	"github.com/opentracing/opentracing-go"
	"github.com/opentracing/opentracing-go/log"
	zipkinot "github.com/openzipkin-contrib/zipkin-go-opentracing"
	"opentracing-study/common"
	"time"
)

// from: https://github.com/opentracing/specification/blob/master/semantic_conventions.md

func main() {
	trace, err := common.NewZipkin(common.ServerAppID, "127.0.0.1:8000")
	if err != nil {
		panic(err)
	}
	// 将zipkin包装为opentracing
	opentracing.SetGlobalTracer(zipkinot.Wrap(trace))
	ctx := context.TODO()
	// span
	span, ctx := opentracing.StartSpanFromContext(ctx, "http")
	span.SetTag("http.kind", "server")
	span.SetTag("http.url", "xxxxxx")
	span.SetTag("http.method", "GET")
	span.SetTag("http.status_code", 200)
	time.Sleep(50 * time.Millisecond) // wait 50ms
	span.Finish()
	// get traceID
	printInfo(span.Context())

	// 根据context创建子span
	span, _ = opentracing.StartSpanFromContext(ctx, "db")
	span.SetTag("span.kind", "client")
	span.SetTag("db.instance", "mysql://127.0.0.1:3306/test")
	span.SetTag("db.statement", "SELECT * FROM user_table")
	span.SetTag("db.type", "mysql")
	time.Sleep(50 * time.Millisecond) // wait 50ms
	// set error tag(设置该tag是为了告知收集器（zipkin等）我发生了错误)
	span.SetTag("error", true)
	// error log
	span.LogFields(
		log.String("event", "error"),
		log.String("message", "testErrorMessage"))
	span.Finish()
	// get traceID
	printInfo(span.Context())

	time.Sleep(10 * time.Second)
}

// printInfo show traceID parentID
func printInfo(span opentracing.SpanContext) {
	zpkCtx := span.(zipkinot.SpanContext)
	var (
		traceID  = zpkCtx.TraceID.String()
		spanID   = zpkCtx.ID.String()
		parentID string
	)
	if zpkCtx.ParentID != nil {
		parentID = zpkCtx.ParentID.String()
	} else {
		parentID = "nil"
	}
	fmt.Printf("\nTraceID:%s   SpanID：%s   ParentID:%s\n", traceID, spanID, parentID)
}
